<!DOCTYPE html>
<html lang="zh">
    <head>
    <!--
        © Material Theme
        https://github.com/viosey/hexo-theme-material
        Version: 1.3.4 -->

    <!-- Title -->
    
    <title>
        
            Servlet-监听器（ServletContext、Request、Session） | 
        
        Twilight&#39;s Blog
    </title>

    <!-- Meta & Info -->
    <meta charset="utf-8">

    <!-- dns prefetch -->
    <meta http-equiv="x-dns-prefetch-control" content="on">
    
    
        <link rel="dns-prefetch" href="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"/>
    
    
        <link rel="dns-prefetch" href="https://changyan.sohu.com"/>
    
    
    
    

    <meta http-equiv="X-UA-Compatible">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="theme-color" content="#0097A7">
    <meta name="author" content="wangchao">
    <meta name="description" content="null">
    <meta name="keywords" content="null,Servlet">

    <!-- Favicons -->
    <link rel="icon shortcut" type="image/ico" href="/img/favicon.png">
    <link rel="icon" sizes="192x192" href="/img/favicon.png">
    <link rel="apple-touch-icon" href="/img/favicon.png">

    <!--iOS -->
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-title" content="Title">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="HandheldFriendly" content="True">
    <meta name="MobileOptimized" content="480">

    <!-- Add to homescreen for Chrome on Android -->
    <meta name="mobile-web-app-capable" content="yes">

    <!-- Add to homescreen for Safari on iOS -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="Twilight&#39;s Blog">

    <!-- The Open Graph protocol -->
    <meta property="og:url" content="http://yoursite.com">
    <meta property="og:type" content="blog">
    <meta property="og:title" content="Servlet-监听器（ServletContext、Request、Session） | Twilight&#39;s Blog">
    <meta property="og:description" content="null">
    <meta property="og:article:tag" content="Servlet"> 

    <!--[if lte IE 9]>
        <link rel="stylesheet" href="/css/ie-blocker.css">

        
            <script src="/js/ie-blocker.zhCN.js"></script>
        
    <![endif]-->

    <!-- Import CSS & jQuery -->
    
        <link rel="stylesheet" href="/css/material.min.css">
        <link rel="stylesheet" href="/css/style.min.css">
        <!-- Config CSS -->


<!-- Other Styles -->
<style>
  body, html {
    font-family: Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
  }

  a {
    color: #00838F;
  }

  .mdl-card__media,
  #search-label,
  #search-form-label:after,
  #scheme-Paradox .hot_tags-count,
  #scheme-Paradox .sidebar_archives-count,
  #scheme-Paradox .sidebar-colored .sidebar-header,
  #scheme-Paradox .sidebar-colored .sidebar-badge{
    background-color: #0097A7 !important;
  }

  /* Sidebar User Drop Down Menu Text Color */
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:hover,
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:focus {
    color: #0097A7 !important;
  }

  #post_entry-right-info,
  .sidebar-colored .sidebar-nav li:hover > a,
  .sidebar-colored .sidebar-nav li:hover > a i,
  .sidebar-colored .sidebar-nav li > a:hover,
  .sidebar-colored .sidebar-nav li > a:hover i,
  .sidebar-colored .sidebar-nav li > a:focus i,
  .sidebar-colored .sidebar-nav > .open > a,
  .sidebar-colored .sidebar-nav > .open > a:hover,
  .sidebar-colored .sidebar-nav > .open > a:focus,
  #ds-reset #ds-ctx .ds-ctx-entry .ds-ctx-head a {
    color: #0097A7 !important;
  }

  .toTop {
    background: #757575 !important;
  }

  .material-layout .material-post>.material-nav,
  .material-layout .material-index>.material-nav,
  .material-nav a {
    color: #757575;
  }

  #scheme-Paradox .MD-burger-layer {
    background-color: #757575;
  }

  #scheme-Paradox #post-toc-trigger-btn {
    color: #757575;
  }

  .post-toc a:hover {
    color: #00838F;
    text-decoration: underline;
  }

</style>


<!-- Theme Background Related-->

    <style>
      body{
        background-image: url(/img/bg.jpg);
      }
    </style>




<!-- Fade Effect -->

    <style>
      .fade {
        transition: all 800ms linear;
        -webkit-transform: translate3d(0,0,0);
        -moz-transform: translate3d(0,0,0);
        -ms-transform: translate3d(0,0,0);
        -o-transform: translate3d(0,0,0);
        transform: translate3d(0,0,0);
        opacity: 1;
      }

      .fade.out{
        opacity: 0;
      }
    </style>


        <script src="/js/jquery.min.js"></script>
        <script src="/js/queue.js"></script>
    

    <!-- UC Browser Compatible -->
    <script>
        var agent = navigator.userAgent.toLowerCase();
        if(agent.indexOf('ucbrowser')>0) {
            document.write("<link rel=\"stylesheet\" href=\"/css/uc.css\">");
            alert('由于 UC 浏览器使用极旧的内核，而本网站使用了一些新的特性。\n为了您能更好的浏览，推荐使用 Chrome 或 Firefox 浏览器。');
        }
    </script>

    

    


    <!-- Bing Background -->
    

    <!-- Custom Head -->
    
</head>


    
        <body id="scheme-Paradox" class="lazy">
            <div class="material-layout  mdl-js-layout has-drawer is-upgraded">
                

                <!-- Main Container -->
                <main class="material-layout__content" id="main">

                    <!-- Top Anchor -->
                    <div id="top"></div>

                    
                        <!-- Hamburger Button -->
                        <button class="MD-burger-icon sidebar-toggle">
                            <span class="MD-burger-layer"></span>
                        </button>
                    

                    <!-- Post TOC -->

    
    <!-- Back Button -->
    <!--
    <div class="material-back" id="backhome-div" tabindex="0">
        <a class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
           href="#" onclick="window.history.back();return false;"
           target="_self"
           role="button"
           data-upgraded=",MaterialButton,MaterialRipple">
            <i class="material-icons" role="presentation">arrow_back</i>
            <span class="mdl-button__ripple-container">
                <span class="mdl-ripple"></span>
            </span>
        </a>
    </div>
    -->

    <!-- Left aligned menu below button -->
    <button id="post-toc-trigger-btn"
        class="mdl-button mdl-js-button mdl-button--icon">
        <i class="material-icons">format_list_numbered</i>
    </button>

    <ul class="post-toc-wrap mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="post-toc-trigger-btn" style="max-height:80vh; overflow-y:scroll;">
        <ol class="post-toc"><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#ServletContextListener"><span class="post-toc-number">1.</span> <span class="post-toc-text">ServletContextListener</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#ServletContext"><span class="post-toc-number">1.1.</span> <span class="post-toc-text">ServletContext</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#配置监听器"><span class="post-toc-number">1.2.</span> <span class="post-toc-text">配置监听器</span></a></li></ol></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#HttpSessionListener"><span class="post-toc-number">2.</span> <span class="post-toc-text">HttpSessionListener</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#控制失效时间"><span class="post-toc-number">2.1.</span> <span class="post-toc-text">控制失效时间</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#配置监听器-1"><span class="post-toc-number">2.2.</span> <span class="post-toc-text">配置监听器</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#作用"><span class="post-toc-number">2.3.</span> <span class="post-toc-text">作用</span></a></li></ol></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#ServletRequestListener"><span class="post-toc-number">3.</span> <span class="post-toc-text">ServletRequestListener</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#配置监听器-2"><span class="post-toc-number">3.1.</span> <span class="post-toc-text">配置监听器</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#作用-1"><span class="post-toc-number">3.2.</span> <span class="post-toc-text">作用</span></a></li></ol></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#对象中增加和删除属性的事件监听器"><span class="post-toc-number">4.</span> <span class="post-toc-text">对象中增加和删除属性的事件监听器</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#HttpSession-中对象状态（绑定、解除）"><span class="post-toc-number">5.</span> <span class="post-toc-text">HttpSession 中对象状态（绑定、解除）</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#HttpSessionBindingListener"><span class="post-toc-number">5.1.</span> <span class="post-toc-text">HttpSessionBindingListener</span></a></li></ol></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#钝化和活化"><span class="post-toc-number">6.</span> <span class="post-toc-text">钝化和活化</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#什么时候钝化"><span class="post-toc-number">6.1.</span> <span class="post-toc-text">什么时候钝化</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#HttpSessionActivationListener"><span class="post-toc-number">6.2.</span> <span class="post-toc-text">HttpSessionActivationListener</span></a></li></ol></li></ol>

        <!--
        <li class="mdl-menu__item">
            Some Action
        </li>
        -->
    </ul>




<!-- Layouts -->

    <!-- Post Module -->
    <div class="material-post_container">

        <div class="material-post mdl-grid">
            <div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">

                <!-- Post Header(Thumbnail & Title) -->
                
    <!-- Paradox Post Header -->
    
        <!-- Custom Thumbnail -->
        <div class="post_thumbnail-custom mdl-card__media mdl-color-text--grey-50" style="background-image:url(http://i4.piimg.com/584041/f4d1744d238551e9.jpg)">
    
            <p class="article-headline-p">
                Servlet-监听器（ServletContext、Request、Session）
            </p>
        </div>





                
                    <!-- Paradox Post Info -->
                    <div class="mdl-color-text--grey-700 mdl-card__supporting-text meta">

    <!-- Author Avatar -->
    <div id="author-avatar">
        <img src="/img/avatar.png" width="44px" height="44px" alt="Author Avatar"/>
    </div>
    <!-- Author Name & Date -->
    <div>
        <strong>wangchao</strong>
        <span>6月 26, 2017</span>
    </div>

    <div class="section-spacer"></div>

    <!-- Favorite -->
    <!--
        <button id="article-functions-like-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon btn-like">
            <i class="material-icons" role="presentation">favorite</i>
            <span class="visuallyhidden">favorites</span>
        </button>
    -->

    <!-- Qrcode -->
    

    <!-- Tags (bookmark) -->
    
    <button id="article-functions-viewtags-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
        <i class="material-icons" role="presentation">bookmark</i>
        <span class="visuallyhidden">bookmark</span>
    </button>
    <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-functions-viewtags-button">
        <li class="mdl-menu__item">
        <a class="post_tag-link" href="/tags/Servlet/">Servlet</a>
    </ul>
    

    <!-- Share -->
    <button id="article-fuctions-share-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
    <i class="material-icons" role="presentation">share</i>
    <span class="visuallyhidden">share</span>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-fuctions-share-button">
    
    <!-- Leancloud Views -->
        <a class="post_share-link" href="#">
            <li class="mdl-menu__item">
                <span id="/2017/06/26/Servlet-监听器（ServletContext、Request、Session）/" class="leancloud-views_num" data-flag-title="Servlet-监听器（ServletContext、Request、Session）">
     &nbsp;浏览量
</span>

            </li>
        </a>
    

    

    <!-- Share Weibo -->
    
        <a class="post_share-link" href="http://service.weibo.com/share/share.php?appkey=&title=Servlet-监听器（ServletContext、Request、Session）&url=http://yoursite.com//2017/06/26/Servlet-监听器（ServletContext、Request、Session）/index.html&pic=&searchPic=false&style=simple" target="_blank">
            <li class="mdl-menu__item">
                分享到微博
            </li>
        </a>
    

    <!-- Share Twitter -->
    
        <a class="post_share-link" href="https://twitter.com/intent/tweet?text=Servlet-监听器（ServletContext、Request、Session）&url=http://yoursite.com//2017/06/26/Servlet-监听器（ServletContext、Request、Session）/index.html&via=wangchao" target="_blank">
            <li class="mdl-menu__item">
                分享到 Twitter
            </li>
        </a>
    

    <!-- Share Facebook -->
    
        <a class="post_share-link" href="https://www.facebook.com/sharer/sharer.php?u=http://yoursite.com//2017/06/26/Servlet-监听器（ServletContext、Request、Session）/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Facebook
            </li>
        </a>
    

    <!-- Share Google+ -->
    
        <a class="post_share-link" href="https://plus.google.com/share?url=http://yoursite.com//2017/06/26/Servlet-监听器（ServletContext、Request、Session）/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Google+
            </li>
        </a>
    

    <!-- Share LinkedIn -->
    

    <!-- Share QQ -->
    
        <a class="post_share-link" href="http://connect.qq.com/widget/shareqq/index.html?site=Twilight&#39;s Blog&title=Servlet-监听器（ServletContext、Request、Session）&summary=null&pics=http://yoursite.com/img/favicon.png&url=http://yoursite.com/2017/06/26/Servlet-监听器（ServletContext、Request、Session）/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 QQ
            </li>
        </a>
    

    <!-- Share Telegram -->
    
</ul>

</div>

                

                <!-- Post Content -->
                <div id="post-content" class="mdl-color-text--grey-700 mdl-card__supporting-text fade out">
    
        <h1 id="ServletContextListener"><a href="#ServletContextListener" class="headerlink" title="ServletContextListener"></a>ServletContextListener</h1><p>ServletContext对象创建和销毁时触发的监听器<br>该对象有两个方法,分别是contextInitialized() 和contextDestroyed() 对应着ServletContext对象的创建与销毁。一个ServletContext可以有多个listener<br><a id="more"></a></p>
<h2 id="ServletContext"><a href="#ServletContext" class="headerlink" title="ServletContext"></a>ServletContext</h2><p>一个web应用对应着一个ServletContext，ServletContext的根目录为当前web应用的webRoot目录</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">public class FirstListener implements ServletContextListener &#123;</div><div class="line"></div><div class="line">	public void contextDestroyed(ServletContextEvent arg0) &#123;</div><div class="line">		System.out.println(&quot;###contextDestroy&quot;);</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void contextInitialized(ServletContextEvent arg0) &#123;</div><div class="line">		ServletContext context = arg0.getServletContext();</div><div class="line">		for(Object temp : context.getResourcePaths(&quot;/&quot;))&#123;</div><div class="line">			System.out.println(temp);</div><div class="line">		&#125;</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>结果是：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">/index.jsp</div><div class="line">/WEB-INF/</div><div class="line">/META-INF/</div></pre></td></tr></table></figure></p>
<h2 id="配置监听器"><a href="#配置监听器" class="headerlink" title="配置监听器"></a>配置监听器</h2><p>在web.xml中添加一下内容：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">&lt;listener&gt;</div><div class="line">    &lt;listener-class&gt;com.twilight.listener.FirstListener&lt;/listener-class&gt;</div><div class="line">&lt;/listener&gt;</div></pre></td></tr></table></figure></p>
<h1 id="HttpSessionListener"><a href="#HttpSessionListener" class="headerlink" title="HttpSessionListener"></a>HttpSessionListener</h1><p>在浏览器中访问<a href="http://localhost:8080/FirstFilter" target="_blank" rel="external">http://localhost:8080/FirstFilter</a> 时会创建session，tomcat会输出sessionCreated，一段时间后session会自动失效，然后tomcat会输出sessionDestroyed<br>一个Session对应多个listener</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">public void sessionCreated(HttpSessionEvent arg0) &#123;</div><div class="line">	System.out.println(&quot;sessionCreated&quot;);</div><div class="line">&#125;</div><div class="line"></div><div class="line">public void sessionDestroyed(HttpSessionEvent arg0) &#123;</div><div class="line">	System.out.println(&quot;sessionDestroyed&quot;);</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h2 id="控制失效时间"><a href="#控制失效时间" class="headerlink" title="控制失效时间"></a>控制失效时间</h2><p>在web.xml 中配置session-timeout 以分钟为单位。当时间是0或复数时表示永久存在。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">&lt;session-config&gt;</div><div class="line">	&lt;session-timeout&gt;1&lt;/session-timeout&gt;</div><div class="line">&lt;/session-config&gt;</div></pre></td></tr></table></figure></p>
<h2 id="配置监听器-1"><a href="#配置监听器-1" class="headerlink" title="配置监听器"></a>配置监听器</h2><p>在web.xml中添加一下内容：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">&lt;listener&gt;</div><div class="line">    &lt;listener-class&gt;com.twilight.listener.MyHttpSessionListener&lt;/listener-class&gt;</div><div class="line">&lt;/listener&gt;</div></pre></td></tr></table></figure></p>
<h2 id="作用"><a href="#作用" class="headerlink" title="作用"></a>作用</h2><ul>
<li>统计在线人数</li>
<li>记录访问日志</li>
</ul>
<h1 id="ServletRequestListener"><a href="#ServletRequestListener" class="headerlink" title="ServletRequestListener"></a>ServletRequestListener</h1><p>表示用户请求的监听<br>两个方法：requestInitialized() 和requestDestroyed()<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">public void requestDestroyed(ServletRequestEvent arg0) &#123;</div><div class="line">	System.out.println(&quot;requestDestroyed&quot;);</div><div class="line">&#125;</div><div class="line"></div><div class="line">public void requestInitialized(ServletRequestEvent arg0) &#123;</div><div class="line">	System.out.println(&quot;requestInitialized&quot;);</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>结果是：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">requestInitialized</div><div class="line">sessionCreated</div><div class="line">requestDestroyed</div></pre></td></tr></table></figure></p>
<h2 id="配置监听器-2"><a href="#配置监听器-2" class="headerlink" title="配置监听器"></a>配置监听器</h2><p>在web.xml中添加一下内容：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">&lt;listener&gt;</div><div class="line">	&lt;listener-class&gt;com.twilight.listener.MyServletRequestListener&lt;/listener-class&gt;</div><div class="line">&lt;/listener&gt;</div></pre></td></tr></table></figure></p>
<h2 id="作用-1"><a href="#作用-1" class="headerlink" title="作用"></a>作用</h2><ul>
<li>读取参数</li>
<li>记录访问历史</li>
</ul>
<h1 id="对象中增加和删除属性的事件监听器"><a href="#对象中增加和删除属性的事件监听器" class="headerlink" title="对象中增加和删除属性的事件监听器"></a>对象中增加和删除属性的事件监听器</h1><p>三个事件都有对应的属性监听器：</p>
<ul>
<li><strong>ServletContext</strong> —  <strong>ServletContextAttributeListener</strong></li>
<li><strong>HttpSession</strong> — <strong>HttpSessionAttributeListener</strong></li>
<li><strong>ServletRequest</strong> —  <strong>ServletRequestAttributeListener</strong></li>
</ul>
<p>每个属性监听器都有三个方法：</p>
<ul>
<li>attributeAdded    () 监听属性的增加</li>
<li>attributeRemoved() 监听属性的移除</li>
<li>attributeReplaced() 监听属性的替换</li>
</ul>
<p>ServletRequestAttributeListener 代码如下，其他监听器代码类似：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">public class MyServletRequestAttributeListener implements</div><div class="line">		ServletRequestAttributeListener &#123;</div><div class="line"></div><div class="line">	public void attributeAdded(ServletRequestAttributeEvent arg0) &#123;</div><div class="line">		System.out.println(&quot;ServletRequestAttributeListener_attributeAdded_&quot;+arg0.getName());</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void attributeRemoved(ServletRequestAttributeEvent arg0) &#123;</div><div class="line">		System.out.println(&quot;ServletRequestAttributeListener_attributeRemoved_&quot;+arg0.getName());</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void attributeReplaced(ServletRequestAttributeEvent arg0) &#123;</div><div class="line">		System.out.println(&quot;ServletRequestAttributeListener_attributeReplaced_&quot;+arg0.getName());</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>addAttribute.jsp模拟增加属性<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">request.setAttribute(&quot;ServletRequest&quot;, &quot;ServletRequestValue&quot;);</div><div class="line">session.setAttribute(&quot;Session&quot;, &quot;SessionValue&quot;);</div><div class="line">session.getServletContext().setAttribute(&quot;ServletContext&quot;, &quot;ServletContextValue&quot;);</div></pre></td></tr></table></figure></p>
<p>removeAttribute.jsp 模拟移除属性<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">request.removeAttribute(&quot;ServletRequest&quot;);</div><div class="line">session.removeAttribute(&quot;Session&quot;);</div><div class="line">session.getServletContext().removeAttribute(&quot;ServletContext&quot;);</div></pre></td></tr></table></figure></p>
<p>第一次访问addAttribute.jsp:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">requestInitialized</div><div class="line">ServletRequestAttributeListener_attributeReplaced_org.apache.catalina.ASYNC_SUPPORTED</div><div class="line">ServletRequestAttributeListener_attributeAdded_ServletRequest</div><div class="line">HttpSessionAttributeListener_attributeAdded_Session</div><div class="line">ServletContextAttributeListener_attributeAdded_ServletContext</div><div class="line">requestDestroyed</div></pre></td></tr></table></figure></p>
<p>重复访问,发现只有Request是add，因为之前的Request已经失效，此时的Request是新创建的对象：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">requestInitialized</div><div class="line">ServletRequestAttributeListener_attributeReplaced_org.apache.catalina.ASYNC_SUPPORTED</div><div class="line">ServletRequestAttributeListener_attributeAdded_ServletRequest</div><div class="line">HttpSessionAttributeListener_attributeReplaced_Session</div><div class="line">ServletContextAttributeListener_attributeReplaced_ServletContext</div><div class="line">requestDestroyed</div></pre></td></tr></table></figure></p>
<p>访问removeAttribute.jsp,此时之前的Request对象已经被销毁，所以不会看到request被remove<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">requestInitialized</div><div class="line">ServletRequestAttributeListener_attributeReplaced_org.apache.catalina.ASYNC_SUPPORTED</div><div class="line">HttpSessionAttributeListener_attributeRemoved_Session</div><div class="line">ServletContextAttributeListener_attributeRemoved_ServletContext</div><div class="line">requestDestroyed</div></pre></td></tr></table></figure></p>
<h1 id="HttpSession-中对象状态（绑定、解除）"><a href="#HttpSession-中对象状态（绑定、解除）" class="headerlink" title="HttpSession 中对象状态（绑定、解除）"></a>HttpSession 中对象状态（绑定、解除）</h1><ul>
<li>绑定 ：将对象保存到session中</li>
<li>解除 ：从session中移除对象</li>
</ul>
<h2 id="HttpSessionBindingListener"><a href="#HttpSessionBindingListener" class="headerlink" title="HttpSessionBindingListener"></a>HttpSessionBindingListener</h2><p>该类类似一个javabean保存一些需要的信息，它有两个必须的方法：</p>
<ul>
<li><strong>valueBound() </strong> <strong>绑定</strong></li>
<li><strong>valueUnbound() </strong> <strong>解绑定</strong></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div></pre></td><td class="code"><pre><div class="line">package com.twilight.entity;</div><div class="line"></div><div class="line">import javax.servlet.http.HttpSessionBindingEvent;</div><div class="line">import javax.servlet.http.HttpSessionBindingListener;</div><div class="line"></div><div class="line">public class User implements HttpSessionBindingListener &#123;</div><div class="line">	private String userName ;</div><div class="line">	private String password ;</div><div class="line">	</div><div class="line"></div><div class="line">	public void valueBound(HttpSessionBindingEvent arg0) &#123;</div><div class="line">		System.out.println(&quot;HttpSessionBindingListener_valueBound_&quot;+arg0.getName());</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void valueUnbound(HttpSessionBindingEvent arg0) &#123;</div><div class="line">		System.out.println(&quot;HttpSessionBindingListener_valueUnbound+&quot;+arg0.getName());</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public String getUserName() &#123;</div><div class="line">		return userName;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void setUserName(String userName) &#123;</div><div class="line">		this.userName = userName;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public String getPassword() &#123;</div><div class="line">		return password;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void setPassword(String password) &#123;</div><div class="line">		this.password = password;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>该类不需要注册，可以直接使用<strong>，因为他可以认为只是一个继承了HttpSessionBindingListener接口的Javabean</strong>，使用方法：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">session.setAttribute(&quot;userObj&quot;, new User());</div></pre></td></tr></table></figure></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">session.removeAttribute(&quot;userObj&quot;);</div></pre></td></tr></table></figure>
<p>结果是：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">// 绑定</div><div class="line">requestInitialized</div><div class="line">HttpSessionBindingListener_valueBound_userObj</div><div class="line">requestDestroyed</div><div class="line"></div><div class="line">// 解绑定</div><div class="line">requestInitialized</div><div class="line">HttpSessionBindingListener_valueUnbound+userObj</div><div class="line">requestDestroyed</div></pre></td></tr></table></figure></p>
<h1 id="钝化和活化"><a href="#钝化和活化" class="headerlink" title="钝化和活化"></a>钝化和活化</h1><ul>
<li>钝化 将session序列化到磁盘</li>
<li>活化 将序列化的对象反序列化到内存中</li>
</ul>
<h2 id="什么时候钝化"><a href="#什么时候钝化" class="headerlink" title="什么时候钝化"></a>什么时候钝化</h2><ul>
<li>当tomcat服务器关闭或重启时，会将当前的session对象钝化</li>
<li>当web应用被重新加载时（reload）钝化</li>
</ul>
<p><strong>当tomcat服务器重启开启时，重新加载文件道内存并删除本地文件</strong></p>
<h2 id="HttpSessionActivationListener"><a href="#HttpSessionActivationListener" class="headerlink" title="HttpSessionActivationListener"></a>HttpSessionActivationListener</h2><p>实现钝化和话的接口，具体方法有两个：</p>
<ul>
<li><strong>sessionWillPassivate</strong> <strong>钝化</strong></li>
<li><strong>sessionDidActivate</strong> <strong>活化</strong></li>
</ul>
<p>由于钝化需要将对象序列化，所以还需要实现Serializable接口。代码如下：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div></pre></td><td class="code"><pre><div class="line">package com.twilight.entity;</div><div class="line"></div><div class="line">import java.io.Serializable;</div><div class="line"></div><div class="line">import javax.servlet.http.HttpSessionActivationListener;</div><div class="line">import javax.servlet.http.HttpSessionBindingEvent;</div><div class="line">import javax.servlet.http.HttpSessionBindingListener;</div><div class="line">import javax.servlet.http.HttpSessionEvent;</div><div class="line"></div><div class="line">public class User implements HttpSessionBindingListener ,HttpSessionActivationListener ,Serializable &#123;</div><div class="line">	private String userName ;</div><div class="line">	private String password ;</div><div class="line">	</div><div class="line"></div><div class="line">	public void valueBound(HttpSessionBindingEvent arg0) &#123;</div><div class="line">		System.out.println(&quot;HttpSessionBindingListener_valueBound_&quot;+arg0.getName());</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void valueUnbound(HttpSessionBindingEvent arg0) &#123;</div><div class="line">		System.out.println(&quot;HttpSessionBindingListener_valueUnbound+&quot;+arg0.getName());</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public String getUserName() &#123;</div><div class="line">		return userName;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void setUserName(String userName) &#123;</div><div class="line">		this.userName = userName;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public String getPassword() &#123;</div><div class="line">		return password;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void setPassword(String password) &#123;</div><div class="line">		this.password = password;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	</div><div class="line">	public void sessionDidActivate(HttpSessionEvent se) &#123;</div><div class="line">		System.out.println(&quot;HttpSessionActivationListener_sessionDidActivate_&quot;+se.getSource());</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	public void sessionWillPassivate(HttpSessionEvent se) &#123;</div><div class="line">		System.out.println(&quot;HttpSessionActivationListener_sessionWillPassivate_&quot;+se.getSource());</div><div class="line">	&#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>结果：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">// 钝化</div><div class="line">HttpSessionActivationListener_sessionWillPassivate_org.apache.catalina.session.StandardSessionFacade@720a366b</div><div class="line"></div><div class="line">// 活化</div><div class="line">HttpSessionActivationListener_sessionDidActivate_org.apache.catalina.session.StandardSessionFacade@798aa3f4</div></pre></td></tr></table></figure></p>
<p>钝化后的文件保存在 Tomcat\work\Catalina\localhost\项目名\SESSIONS.ser文件中，服务器启动后文件被反序列化，然后被删除</p>
<p>参考资料：<a href="http://www.imooc.com/learn/271" title="Fcming" target="_blank" rel="external">http://www.imooc.com/learn/271</a></p>

    

    
</div>


                

                <!-- Post Comments -->
                
                    


    <!-- 使用 changyan -->
    <div id="changyan-comment">
        <!--PC和WAP自适应版-->
<div id="SOHUCS" sid="2017/06/26/Servlet-监听器（ServletContext、Request、Session）/"  ></div>
<script type="text/javascript">
(function(){
var appid = 'cysVH2p6S';
var conf = '7d191ef850d424bb873df33179309db5';
var width = window.innerWidth || document.documentElement.clientWidth;
if (width < 960) {
window.document.write('<script id="changyan_mobile_js" charset="utf-8" type="text/javascript" src="https://changyan.sohu.com/upload/mobile/wap-js/changyan_mobile.js?client_id=' + appid + '&conf=' + conf + '"><\/script>'); } else { var loadJs=function(d,a){var c=document.getElementsByTagName("head")[0]||document.head||document.documentElement;var b=document.createElement("script");b.setAttribute("type","text/javascript");b.setAttribute("charset","UTF-8");b.setAttribute("src",d);if(typeof a==="function"){if(window.attachEvent){b.onreadystatechange=function(){var e=b.readyState;if(e==="loaded"||e==="complete"){b.onreadystatechange=null;a()}}}else{b.onload=a}}c.appendChild(b)};loadJs("https://changyan.sohu.com/upload/changyan.js",function(){window.changyan.api.config({appid:appid,conf:conf})}); } })(); </script>

    </div>
    <style>
        #changyan-comment{
            background-color: #eee;
            padding: 2pc;
        }
    </style>






                
            </div>

            <!-- Post Prev & Next Nav -->
            <nav class="material-nav mdl-color-text--grey-50 mdl-cell mdl-cell--12-col">
    <!-- Prev Nav -->
    
        <a href="/2017/06/26/Servlet-监听器获得当前在线人数/" id="post_nav-newer" class="prev-content">
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_back</i>
            </button>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            新篇
        </a>
    

    <!-- Section Spacer -->
    <div class="section-spacer"></div>

    <!-- Next Nav -->
    
        <a href="/2017/06/20/jQuery动画-自定义动画animate/" id="post_nav-older" class="next-content">
            旧篇
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_forward</i>
            </button>
        </a>
    
</nav>

        </div>
    </div>



                    
                        <!-- Overlay For Active Sidebar -->
<div class="sidebar-overlay"></div>

<!-- Material sidebar -->
<aside id="sidebar" class="sidebar sidebar-colored sidebar-fixed-left" role="navigation">
    <div id="sidebar-main">
        <!-- Sidebar Header -->
        <div class="sidebar-header header-cover" style="background-image: url(/img/sidebar_header.jpg);">
    <!-- Top bar -->
    <div class="top-bar"></div>

    <!-- Sidebar toggle button -->
    <button type="button" class="sidebar-toggle mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon" style="display: initial;" data-upgraded=",MaterialButton,MaterialRipple">
        <i class="material-icons">clear_all</i>
        <span class="mdl-button__ripple-container">
            <span class="mdl-ripple">
            </span>
        </span>
    </button>

    <!-- Sidebar Avatar -->
    <div class="sidebar-image">
        <img src="/img/avatar.png" alt="wangchao's avatar">
    </div>

    <!-- Sidebar Email -->
    <a data-toggle="dropdown" class="sidebar-brand" href="#settings-dropdown">
        twilight0402@163.com
        <b class="caret"></b>
    </a>
</div>


        <!-- Sidebar Navigation  -->
        <ul class="nav sidebar-nav">
    <!-- User dropdown  -->
    <li class="dropdown">
        <ul id="settings-dropdown" class="dropdown-menu">
            
                <li>
                    <a href="http://mail.163.com" target="_blank" title="Email Me">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        Email Me
                    </a>
                </li>
            
        </ul>
    </li>

    <!-- Homepage -->
    
        <li id="sidebar-first-li">
            <a href="/" target="_self">
                
                    <i class="material-icons sidebar-material-icons">home</i>
                
                主页
            </a>
        </li>
        
    

    <!-- Archives  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">inbox</i>
                
                    归档
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
            <li>
                <a class="sidebar_archives-link" href="/archives/2017/08/">八月 2017<span class="sidebar_archives-count">5</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/07/">七月 2017<span class="sidebar_archives-count">23</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/06/">六月 2017<span class="sidebar_archives-count">13</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/04/">四月 2017<span class="sidebar_archives-count">7</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/03/">三月 2017<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/02/">二月 2017<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/01/">一月 2017<span class="sidebar_archives-count">8</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/12/">十二月 2016<span class="sidebar_archives-count">4</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/11/">十一月 2016<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/09/">九月 2016<span class="sidebar_archives-count">3</span></a>
            </ul>
        </li>
        
    

    <!-- Categories  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">chrome_reader_mode</i>
                
                分类
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
                <li>
                <a class="sidebar_archives-link" href="/categories/CSS/">CSS<span class="sidebar_archives-count">9</span></a></li><li><a class="sidebar_archives-link" href="/categories/HTML/">HTML<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/categories/JSP/">JSP<span class="sidebar_archives-count">6</span></a></li><li><a class="sidebar_archives-link" href="/categories/Java/">Java<span class="sidebar_archives-count">8</span></a></li><li><a class="sidebar_archives-link" href="/categories/JavaScript/">JavaScript<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/categories/Linux/">Linux<span class="sidebar_archives-count">13</span></a></li><li><a class="sidebar_archives-link" href="/categories/MySQL/">MySQL<span class="sidebar_archives-count">7</span></a></li><li><a class="sidebar_archives-link" href="/categories/Servlet/">Servlet<span class="sidebar_archives-count">9</span></a></li><li><a class="sidebar_archives-link" href="/categories/jQuery/">jQuery<span class="sidebar_archives-count">7</span></a></li><li><a class="sidebar_archives-link" href="/categories/技术/">技术<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/categories/日常/">日常<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/categories/随笔/">随笔<span class="sidebar_archives-count">3</span></a>
            </ul>
        </li>
        
    

    <!-- Pages  -->
    
        <li>
            <a href="/tags" title="标签云">
                
                    <i class="material-icons sidebar-material-icons">cloud</i>
                
                标签云
            </a>
        </li>
        
            <li class="divider"></li>
        
    
        <li>
            <a href="/about" title="About">
                
                    <i class="material-icons sidebar-material-icons">person</i>
                
                About
            </a>
        </li>
        
    
        <li>
            <a href="/links" title="Social">
                
                    <i class="material-icons sidebar-material-icons">equalizer</i>
                
                Social
            </a>
        </li>
        
    

    <!-- Article Number  -->
    
        <li>
            <a href="/archives">
                文章总数
                <span class="sidebar-badge">71</span>
            </a>
        </li>
        
    
</ul>


        <!-- Sidebar Footer -->
        <!--
I'm glad you use this theme, the development is no so easy, I hope you can keep the copyright, I will thank you so much.
If you still want to delete the copyrights, could you still retain the first one? Which namely "Theme Material"
It will not impact the appearance and can give developers a lot of support :)

很高兴您使用并喜欢该主题，开发不易 十分谢谢与希望您可以保留一下版权声明。
如果您仍然想删除的话 能否只保留第一项呢？即 "Theme Material"
它不会影响美观并可以给开发者很大的支持和动力。 :)
-->

<!-- Sidebar Divider -->

    <div class="sidebar-divider"></div>


<!-- Theme Material -->


<!-- Help & Support -->
<!--

-->

<!-- Feedback -->
<!--

    <a href="https://github.com/viosey/hexo-theme-material/issues" target="_blank" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
        sidebar.feedback
        <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
    </a>

-->

<!-- About Theme -->
<!--

    <a href="https://blog.viosey.com/index.php/Material.html" target="_blank" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
             sidebar.about_theme
            <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
    </a>

-->

    </div>

    <!-- Sidebar Image -->
    

</aside>

                    

                    
                        <!-- Footer Top Button -->
                        <div class="toTop-wrap">
    <a href="#top" class="toTop">
        <i class="material-icons footer_top-i">expand_less</i>
    </a>
</div>

                    

                    <!--Footer-->
<footer class="mdl-mini-footer" id="bottom">
    
        <!-- Paradox Footer Left Section -->
        <div class="mdl-mini-footer--left-section sns-list">
    <!-- Twitter -->
    
        <a href="https://twitter.com/twitter" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn" style="background-image: url(/img/footer/footer_ico-twitter.svg);">
                <span class="visuallyhidden">Twitter</span>
            </button><!--
     --></a>
    

    <!-- Facebook -->
    
        <a href="https://www.facebook.com/facebook" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn" style="background-image: url(/img/footer/footer_ico-facebook.svg);">
                <span class="visuallyhidden">Facebook</span>
            </button><!--
     --></a>
    

    <!-- Google + -->
    
        <a href="https://www.google.com/" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn" style="background-image: url(/img/footer/footer_ico-gplus.svg);">
                <span class="visuallyhidden">Google Plus</span>
            </button><!--
     --></a>
    

    <!-- Weibo -->
    

    <!-- Instagram -->
    

    <!-- Tumblr -->
    

    <!-- Github -->
    
        <a href="https://github.com/1601436878" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn" style="background-image: url(/img/footer/footer_ico-github.svg);">
                <span class="visuallyhidden">Github</span>
            </button><!--
     --></a>
    

    <!-- LinkedIn -->
    

    <!-- Zhihu -->
    
        <a href="https://www.zhihu.com/people/wang-chao-50-78/activities" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn" style="background-image: url(/img/footer/footer_ico-zhihu.svg);">
                <span class="visuallyhidden">Zhihu</span>
            </button><!--
     --></a>
    

    <!-- Bilibili -->
    

    <!-- Telegram -->
    
</div>


        <!--Copyright-->
        <div id="copyright">
            Copyright&nbsp;©&nbsp;
            <script type="text/javascript">
                var fd = new Date();
                document.write(fd.getFullYear());
            </script>
            &nbsp;Twilight's Blog
        </div>

        <!-- Paradox Footer Right Section -->

        <!--
        I am glad you use this theme, the development is no so easy, I hope you can keep the copyright.
        It will not impact the appearance and can give developers a lot of support :)

        很高兴您使用该主题，开发不易，希望您可以保留一下版权声明。
        它不会影响美观并可以给开发者很大的支持。 :)
        -->

        <div class="mdl-mini-footer--right-section">
            <div>
                <div class="footer-develop-div">Powered by <a href="https://hexo.io" target="_blank" class="footer-develop-a">Hexo</a></div>
                <div class="footer-develop-div">Theme - <a href="https://github.com/viosey/hexo-theme-material" target="_blank" class="footer-develop-a">Material</a></div>
            </div>
        </div>
    
</footer>


                    <!-- Import File -->

    <script src="/js/lazyload.min.js"></script>
    <script src="/js/js.min.js"></script>



    <script src="/js/nprogress.js"></script>


<script type="text/javascript">
    NProgress.configure({
        showSpinner: true
    });
    NProgress.start();
    $('#nprogress .bar').css({
        'background': '#29d'
    });
    $('#nprogress .peg').css({
        'box-shadow': '0 0 10px #29d, 0 0 15px #29d'
    });
    $('#nprogress .spinner-icon').css({
        'border-top-color': '#29d',
        'border-left-color': '#29d'
    });
    setTimeout(function() {
        NProgress.done();
        $('.fade').removeClass('out');
    }, 800);
</script>





    <!-- Leancloud -->
    <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
    <script>
        AV.initialize('WJXlEXdVypRaytiRUYDL9Q4w-gzGzoHsz', 'qNN24AGgbaMqnDE7lqK8pwCD');
    </script>
    <script>
    function showTime(Counter) {
        var query = new AV.Query(Counter);
        $('.leancloud-views_num').each(function() {
            var url = $(this).attr('id').trim();
            query.equalTo('url', url);
            query.find({
                success: function(results) {
                    if (results.length === 0) {
                        var content = '0 ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                        return;
                    }
                    for (var i = 0; i < results.length; i++) {
                        var object = results[i];
                        var content = object.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    }
                },
                error: function(object, error) {
                    console.log('Error: ' + error.code + ' ' + error.message);
                }
            });
        });
    }

    function addCount(Counter) {
      var Counter = AV.Object.extend('Counter');
      url = $('.leancloud-views_num').attr('id').trim();
      title = $('.leancloud-views_num').attr('data-flag-title').trim();
      var query = new AV.Query(Counter);
      query.equalTo('url', url);
      query.find({
          success: function(results) {
            if (results.length > 0) {
                var counter = results[0];
                counter.fetchWhenSave(true);
                counter.increment('time');
                counter.save(null, {
                    success: function(counter) {
                        var content =  counter.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    },
                    error: function(counter, error) {
                        console.log('Failed to save Visitor num, with error message: ' + error.message);
                    }
                });
            } else {
              var newcounter = new Counter();
              newcounter.set('title', title);
              newcounter.set('url', url);
              newcounter.set('time', 1);
              newcounter.save(null, {
                  success: function(newcounter) {
                      console.log('newcounter.get(\'time\')='+newcounter.get('time'));
                      var content = newcounter.get('time') + ' ' + $(document.getElementById(url)).text();
                      $(document.getElementById(url)).text(content);
                  },
                  error: function(newcounter, error) {
                      console.log('Failed to create');
                  }
              });
            }
        },
        error: function(error) {
            console.log('Error:' + error.code + ' ' + error.message);
        }
      });
    }
    $(function() {
        var Counter = AV.Object.extend('Counter');
        if ($('.leancloud-views_num').length === 1) {
            addCount(Counter);
        } else if ($('.post-title-link').length > 1) {
            showTime(Counter);
        }
    });
</script>







    <!-- 畅言公共 js 代码 start -->
		<script id="cy_cmt_num" src="https://changyan.sohu.com/upload/plugins/plugins.list.count.js?clientId=cysVH2p6S">
</script>
    <!-- 畅言公共 js 代码 end -->







<!-- Window Load-->
<script>
    $(window).load(function() {
        // Post_Toc parent position fixed
        $('.post-toc-wrap').parent('.mdl-menu__container').css('position', 'fixed');
    });
</script>

<!-- MathJax Load-->

<script>
    <!-- Offer LazyLoad -->
    queue.offer(function(){
        $('.lazy').lazyload({
            effect : 'show'
        });
    });

    <!-- Start Queue -->
    $(document).ready(function(){
        setInterval(function(){
            queue.execNext();
        },200);
    });
</script>

                </main>
            </div>
			<!--  -->
				<!--<script type="text/javascript" count="200" color="0,0,255" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>-->
			<!--  -->
        </body>
    
</html>
